package at.com.vn.chess.service;

import java.util.ArrayList;

import vn.com.bip.office.smart.util.XMLHelper;
import at.com.vn.chess.dao.UserDao;
import at.com.vn.chess.entity.ChessBoardInfo;
import at.com.vn.chess.entity.H;
import at.com.vn.chess.entity.User;
import at.com.vn.chess.util.Const;

public abstract class ShogiService extends BaseService {

	private ChessBoardInfo currentChessBoardInfo;
	private int whosWon;

	public ShogiService( String inputStrXml ) {
		super( inputStrXml );
		logger.info( "Bat dau" );
	}

	public void shogiProcess() {
		updateBoardStatus();
	}

	private void updateBoardStatus() {
		
		logger.info( "updateBoardStatus Function -> Bat dau" );

		currentChessBoardInfo = ( ChessBoardInfo ) XMLHelper
				.convertXMLToListObject( inputStrXml, ChessBoardInfo.class )
				.get( 0 );
		
		whosWon = currentChessBoardInfo.getWhosWon();
		
		String historyXml = "";
		int pos = getPositionOfTableInListTable( chessBoardInfoList, currentChessBoardInfo );
		if( pos < chessBoardInfoList.size() ) {
			// getHistory
			historyXml = createHistoryInfo( chessBoardInfoList.get( pos ), inputStrXml );
			
			chessBoardInfoList.remove( pos );
			chessBoardInfoList.add( inputStrXml );
		}else {
			new RuntimeException();
			logger.error( "Khong lay duoc thong tin cua ban co trong list" );
		}
		
		// Them lich su ban co
		int posOfHistoryStr = getPositionOfTableInListTable( chessBoardHistoryList, currentChessBoardInfo );
		if( posOfHistoryStr < chessBoardHistoryList.size() ) {
			// Noi chuoi
			String combineStr = chessBoardHistoryList.get( posOfHistoryStr );
			combineStr = new StringBuilder( combineStr )
					.append( Const.SEPERATE_MARK_OF_HISTORY )
					.append( historyXml ).toString();

			// update
			chessBoardHistoryList.remove( posOfHistoryStr );
			chessBoardHistoryList.add( combineStr );
		}else {
			chessBoardHistoryList.add( historyXml );
		}

		// Xu ly thang thua
		if ( whosWon != Const.UNDEFINE_VALUE ) {
			processWinLose( whosWon, currentChessBoardInfo );
		}
	}

	@SuppressWarnings( "unchecked" )
	private String createHistoryInfo( String oldXml, String newXml ) {	
		
		logger.info( "createHistoryInfo Function -> Bat dau" );
		
		ArrayList<ChessBoardInfo> oldChessBoardList = ( ArrayList<ChessBoardInfo> ) XMLHelper
				.convertXMLToListObject( oldXml, ChessBoardInfo.class );
		
		ArrayList<ChessBoardInfo> newChessBoardList = ( ArrayList<ChessBoardInfo> ) XMLHelper
				.convertXMLToListObject( newXml, ChessBoardInfo.class );
		
		ArrayList<H> listHistory = new ArrayList<H>(); 
		
		ChessBoardInfo oldInfo;
		ChessBoardInfo newInfo;
		for( int i = 0; i < newChessBoardList.size(); i++ ) {
			oldInfo = oldChessBoardList.get( i );
			newInfo = newChessBoardList.get( i );
			
			if( !oldInfo.getX().equals( newInfo.getX() ) || !oldInfo.getY().equals( newInfo.getY() ) ) {
				H h = new H( i, oldInfo, newInfo );
				listHistory.add( h );
			}
		}
		
		return XMLHelper.convertListObjectToXML( listHistory, Const.HISTORY_PROCESS, H.class );
	}
	
	public void processWinLose( int whosWon, ChessBoardInfo info ) {
		processWinLose( whosWon, info.getBName(), info.getWName(), info.getRId(), info.getTId() );
	}
	
	public void processWinLose( int whosWon, String player1Name, String player2Name, String room, int table ) {
		
		logger.info( "processWinLose Function -> Bat dau" );
		
		String playerWon = "";
		String playerLost = "";
		if ( whosWon == Const.QUAN_DEN ) {
			playerWon = player1Name;
			playerLost = player2Name;
		} else if ( whosWon == Const.QUAN_TRANG ) {
			playerWon = player2Name;
			playerLost = player1Name;
		}

		// Update ket qua vao csdl
		// TODO Lay lai sau khi hoan thanh
		updateWonLostStatus( playerWon, playerLost );

		// 6.11.2011 Reset lich su ban co
		for ( int i = 0; i < chessBoardHistoryList.size(); i++ ) {
			if ( chessBoardHistoryList.get( i ).contains( room )
					&& chessBoardHistoryList.get( i )
							.contains( String.valueOf( table ) ) ) {

				// reset
				chessBoardHistoryList.remove( i );					
				break;
			}
		}
	}

	/**
	 * @param playerWon
	 * @param playerLost
	 */
	private void updateWonLostStatus( String playerWon, String playerLost ) {
		
		logger.info( "updateWonLostStatus Function -> Bat dau" );
		
		// Cap nhat vao CSDL
		UserDao userDao = new UserDao();
		userDao.beginTrans();

		// find user wind
		User userWin = userDao.findUser( playerWon );
		// Update win
		if ( userWin != null ) {
			userWin.setWin( userWin.getWin() + 1 );
			userDao.updateUser( userWin );
		}

		// find user loss
		User userLoss = userDao.findUser( playerLost );
		// Update loss
		if ( userLoss != null ) {
			userLoss.setLoss( userLoss.getLoss() + 1 );
			userDao.updateUser( userLoss );
			userDao.commitTrans();
		}

		userDao.closeTrans();
	}
	
	public int getPositionOfTableInListTable( ArrayList<String> listTable, ChessBoardInfo tableInfo ) {
		
		return getPositionOfTableInListTable( listTable, tableInfo.getRId(), tableInfo.getTId() );
	}
	
	public int getPositionOfTableInListTable( ArrayList<String> listTable, String roomId, int tableId ) {
		
		logger.info( "getPositionOfTableInListTable Function -> Bat dau" );
		
		String roomIdStr = new StringBuilder("<rId>").append( roomId ).append( "</rId>" ).toString();
		String tableIdStr = new StringBuilder("<tId>").append( tableId ).append( "</tId>" ).toString();
		
		int i = 0;		
		for ( String strXml : listTable ) {
			if ( strXml.contains( roomIdStr )
					&& strXml.contains( tableIdStr ) ) {
				break;
			}
			i++;
		}
		
		return i;
	}

}
